package newcrunch.gui.tree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * @author WL
 */
public class TreeSorter 
{
    /*
     * Gives an integer to a type to determine which types will appear 
     * first in the tree
     */
    private int getTypeOrder(TreeNodeType type)
    {
        switch (type)
        {
            case ENUM_CONST:
                return -1;
            
            case PRIVATE_FIELD: 
            case PUBLIC_FIELD:
            case PROTECTED_FIELD: 
            case PACKAGE_FIELD:
                return 0;
                
            case PRIVATE_METHOD: 
            case PUBLIC_METHOD: 
            case PROTECTED_METHOD: 
            case PACKAGE_METHOD:
                return 1;
                
            case CLASS: 
            case INTERFACE: 
            case ENUM: 
            case ANNOTATION:
                return 2;
                
            default:
                return 100;
        }
    }
    
    public void sort(CustomTreeNode node)
    {
        int size = node.getChildCount();
        if (size == 0)
            return;
        
        //recursively sort all children and extract them
        ArrayList<CustomTreeNode> children = new ArrayList<CustomTreeNode>(size);
        for (int i = 0; i < size; i++)
        {
            CustomTreeNode currNode = (CustomTreeNode)node.getChildAt(i);
            sort(currNode);
            children.add(currNode);
        }
        
        //sort them
        Collections.sort(children, new Comparator<CustomTreeNode>(){
            @Override
            public int compare(CustomTreeNode o1, CustomTreeNode o2) {
                int order1 = getTypeOrder(o1.getType());
                int order2 = getTypeOrder(o2.getType());
                
                if (order1 != order2)
                    return order1 - order2;
                
                return ((String)o1.getUserObject()).compareTo((String)o2.getUserObject());
            }            
        });
        
        //remove existing children 
        //and add back them in sorted order
        node.removeAllChildren();
        for (CustomTreeNode newNode : children)
            node.add(newNode);
    }
    

}